package com.xiyounet.login.service.impl;

import com.alibaba.fastjson.JSON;
import com.mysql.cj.util.StringUtils;
import com.xiyounet.login.entity.IUser;
import com.xiyounet.login.service.LoginService;
import com.xiyounet.login.service.UserService;
import com.xiyounet.login.utils.JWTUtils;
import com.xiyounet.login.utils.PhoneVerificationUtils;
import com.xiyounet.login.vo.LoginParam;
import com.xiyounet.login.vo.RegisterParam;
import com.xiyounet.login.vo.Result;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Transactional//开启事务注解，防止注册时系统异常（如redis挂了），但是数据库仍然插入数据
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;

    //加密盐
    private static final String slat = "xiyounet!@#";
    /**
     * 登录功能
     * @param loginParam
     * @return
     */
    @Override
    public Result login(LoginParam loginParam) {
        /**
         * 1. 检查参数是否合法
         * 2. 根据用户名和密码去user表中查询 是否存在
         * 3. 如果不存在 登录失败
         * 4. 如果存在 ，使用jwt 生成token 返回给前端
         * 5. token放入redis当中，redis  token：user信息 设置过期时间
         *  (登录认证的时候 先认证token字符串是否合法，去redis认证是否存在)
         */
        String phone = loginParam.getPhone();
        String password = loginParam.getPassword();
        //校验参数合法性
        if(StringUtils.isNullOrEmpty(phone)
                ||StringUtils.isNullOrEmpty(password)
                ||phone.charAt(0)!='1'
        ){
            return Result.fail(1001,"参数错误");
        }
        password = DigestUtils.md5Hex(password + slat);
        //判断用户存不存在
        IUser user = userService.findUser(phone,password);
        if(user==null){
            return Result.fail(1002,"手机号或密码错误！");
        }
        //user.setStatus(1);
        //存在就生成token存进redis
        String token = JWTUtils.createToken(user.getUserId());
        redisTemplate.opsForValue().set("TOKEN_"+token, JSON.toJSONString(user),1, TimeUnit.DAYS);

        return Result.success(token);
    }

    /**
     * 注册功能
     * @return
     */
    @Override
    public Result doRegister(RegisterParam registerParam) {
        /**
         * 1. 判断参数 是否合法
         * 2. 判断账户是否存在，存在 返回账户已经被注册
         * 3. 不存在，注册用户
         * 4. 生成token
         * 5. 存入redis 并返回
         */
        String phone = registerParam.getPhone();
        String password = registerParam.getPassword();
        String username = registerParam.getUsername();
        String email = registerParam.getEmail();
        String sex = registerParam.getSex();
        //校验参数合法性
        if(StringUtils.isNullOrEmpty(phone)
                ||StringUtils.isNullOrEmpty(password)
                ||StringUtils.isNullOrEmpty(username)
                ||StringUtils.isNullOrEmpty(email)
                ||StringUtils.isNullOrEmpty(sex)
        ){
            return Result.fail(10001,"参数输入不合法!");
        }
        //校验电话号码
        if(!PhoneVerificationUtils.isMobileNO(phone)){
            return Result.fail(10001,"请输入正确的电话号码！");
        }
        //判断号码是否被注册
        IUser iUser1 = userService.getUserByPhone(phone);
        if (iUser1!=null){
            return Result.fail(10003,"该号码已经被注册！");
        }
        //判断昵称是否被注册
        IUser iUser2 = userService.getUserByUserName(username);
        if (iUser2!=null){
            return Result.fail(10003,"该用户名已经被注册！");
        }

        password = DigestUtils.md5Hex(password + slat);
        IUser user = new IUser();
        user.setPhone(phone);
        user.setPassword(password);
        user.setUserName(username);
        user.setEmail(email);
        BigDecimal bigDecimal = new BigDecimal("0.00");
        user.setBalance(bigDecimal);
        user.setStatus(0);
        if(sex.equals("男"))
            user.setSex(1);
        else
            user.setSex(0);
        userService.saveUser(user);

        String token = JWTUtils.createToken(user.getUserId());
        redisTemplate.opsForValue().set("TOKEN_"+token, JSON.toJSONString(user),1, TimeUnit.DAYS);
        return Result.success(token);
    }

    /**
     * 退出登录
     * @param token
     * @return
     */
    @Override
    public Result loginOut(String token) {
        //删除token即可
        redisTemplate.delete("TOKEN_"+token);
        return Result.success();
    }


    /**
     * 验证token
     * @param token
     * @return
     */
    @Override
    public IUser checkToken(String token) {
        if (StringUtils.isNullOrEmpty(token)){
            return null;
        }
        Map<String, Object> stringObjectMap = JWTUtils.checkToken(token);
        if (stringObjectMap == null){
            return null;
        }
        String userJson = (String) redisTemplate.opsForValue().get("TOKEN_" + token);
        if (StringUtils.isNullOrEmpty(userJson)){
            return null;
        }
        IUser user = JSON.parseObject(userJson, IUser.class);

        return user;
    }





}
